/*
* $Id: ResizeHelper.cpp 111 2010-07-01 15:26:44Z volok-aleksej@yandex.ru $
*
* Copyright 2009 by Volokitin Aleksey
* All rights reserved
*
*/
#include "Common/include.h"
#include "ResizeHelper.h"
#include "math.h"

CResizeHelper::sizeBlock::sizeBlock()
: size(0), m_pResizeBlock(NULL){}
CResizeHelper::sizeBlock::sizeBlock(int nSize)
: size(nSize), m_pResizeBlock(NULL){}
CResizeHelper::sizeBlock::~sizeBlock(){
	Reset();
}

bool CResizeHelper::sizeBlock::AddSizeRow(int nSize, int level){
	if(level == 0){
		if(m_aChildBlock.size() == nSizeBlock)
			return false;
		m_aChildBlock.push_back(new sizeBlock(nSize));
	}
	else{
		if(!m_aChildBlock.size() || !m_aChildBlock.back()->AddSizeRow(nSize, level - 1)){
			if(m_aChildBlock.size() == nSizeBlock)
				return false;
			m_aChildBlock.push_back(new sizeBlock());
			m_aChildBlock.back()->AddSizeRow(nSize, level - 1);
		}
	}
	size += nSize;
	return true;
}
std::vector<int> CResizeHelper::sizeBlock::GetPosRow(int posCursor, int& offset){
	int sz = 0;
	std::vector<int> pos;
	for(std::vector<sizeBlock*>::iterator it = m_aChildBlock.begin(); it != m_aChildBlock.end(); it++){
		if(sz + (*it)->size >= posCursor){
			pos = (*it)->GetPosRow(posCursor - sz, offset);
			if(!pos.size())
				offset = sz - posCursor;
			pos.push_back(int(it - m_aChildBlock.begin()));
			break;
		}
		sz += (*it)->size;
	}
	return pos;
}
void CResizeHelper::sizeBlock::BeginResize(int posCursor){
	int sz = 0;
	for(std::vector<sizeBlock*>::iterator it = m_aChildBlock.begin(); it != m_aChildBlock.end(); it++){
		if(sz + (*it)->size >= posCursor){
			m_pResizeBlock = *it;
			(*it)->BeginResize(posCursor - sz);
			break;
		}
		sz += (*it)->size;
	}
}

int CResizeHelper::sizeBlock::SetSize(int cy){
	int offset = 0;
	if(m_pResizeBlock)
		offset = m_pResizeBlock->SetSize(cy);
	else{
		int oldSz = size;
		size = cy;
		return cy - oldSz;
	}
	size += offset;
	return offset;
}

void CResizeHelper::sizeBlock::EndResize(){
	if(m_pResizeBlock)
		m_pResizeBlock->EndResize();
	m_pResizeBlock = NULL;
}

void CResizeHelper::sizeBlock::Reset(){
	for(std::vector<sizeBlock*>::iterator it = m_aChildBlock.begin(); it != m_aChildBlock.end(); it++)
		delete *it;
	m_aChildBlock.clear();
	size = 0;
}

CResizeHelper::CResizeHelper(){
	m_pCurBlock = new sizeBlock;
	m_level = 0;
}
CResizeHelper::~CResizeHelper(){
	delete m_pCurBlock;
}

void CResizeHelper::AddSizeRow(int size){
	if(!m_pCurBlock->AddSizeRow(size, m_level)){
		sizeBlock* pBlock = new sizeBlock(m_pCurBlock->size);
		pBlock->m_aChildBlock.push_back(m_pCurBlock);
		m_pCurBlock = pBlock;
		m_level++;
		m_pCurBlock->AddSizeRow(size, m_level);
	}
}
int CResizeHelper::GetPosRow(int posCursor, int& offset){
	std::vector<int> pos = m_pCurBlock->GetPosRow(posCursor, offset);
	int nPos = 0;
	for(int i = 0; i < (int)pos.size(); i++)
		nPos += pos[i] * (int)pow(double(sizeBlock::nSizeBlock), i);
	return nPos;
}

int CResizeHelper::GetSize(){
	return m_pCurBlock->size;
}

void CResizeHelper::BeginResizeRow(int posCursor){
	m_pCurBlock->BeginResize(posCursor);
}
void CResizeHelper::SetSize(int cy){
	m_pCurBlock->SetSize(cy);
}
void CResizeHelper::EndResizeRow(){
	m_pCurBlock->EndResize();
}

void CResizeHelper::Reset(){
	m_pCurBlock->Reset();
}